package net.kazed.nextaction.database;

import java.util.Date;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;

public class Task {
    /**
     * The content:// style URL for this table
     */
    public static final Uri CONTENT_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/task");
    public static final Uri cTopTasksContentURI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/topTasks");
    public static final Uri cInboxTasksContentURI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/inboxTasks");
    public static final Uri cDueTasksContentURI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/dueTasks");
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.nextaction.task";
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.nextaction.task";

    // used by due tasks to determine query type
    public static final int DAY_MODE = 0;
    public static final int WEEK_MODE = 1;
    public static final int MONTH_MODE = 2;

    /**
     * The default sort order for this table
     */
    public static final String DEFAULT_SORT_ORDER = "created ASC";

    public static final String ID = BaseColumns._ID;
    public static final String DESCRIPTION = "description";
    public static final String DETAILS = "details";
    public static final String CONTEXT_ID = "contextId";
    public static final String PARENT_TASK_ID = "parentTaskId";
    public static final String CREATED_DATE = "created";
    public static final String MODIFIED_DATE = "modified";
    public static final String START_DATE = "startDate";
    public static final String DUE_DATE = "dueDate";
    public static final String DISPLAY_ORDER = "displayOrder";
    public static final String COMPLETE = "complete";
    public static final String TYPE = "type";

    public static final String PROJECT_NAME = "project_name";
    public static final String PROJECT_DEFAULT_CONTEXT_ID = "project_default_context_id";
    public static final String PROJECT_ARCHIVED = "project_archived";

    public static final String CONTEXT_NAME = "context_name";
    public static final String CONTEXT_COLOUR = "context_colour";
    public static final String CONTEXT_ICON = "context_icon";

    /**
     * Projection for all the columns of a task.
     */
    public static final Projection FULL_PROJECTION = new Projection(new String[] { ID, DESCRIPTION, DETAILS, CONTEXT_ID,
                    PARENT_TASK_ID, CREATED_DATE, MODIFIED_DATE, START_DATE, DUE_DATE, DISPLAY_ORDER, COMPLETE, TYPE });

    public static final String INBOX_SELECTION = CONTEXT_ID + " = 0 or " + CONTEXT_ID + " is null";

    private Integer id;
    private String description = "";
    private String details = "";
    private Integer contextId;
    private Integer parentTaskId;
    private Date created;
    private Date modified;
    private Date startDate;
    private Date dueDate;
    private Integer order;
    private Boolean complete;
    private TaskType type;

    public Task(Integer id, String description, String details, Integer contextId, Integer parentTaskId, Date created,
                    Date modified, Date startDate, Date dueDate, Integer order, Boolean complete, TaskType type) {
        this.id = id;
        this.description = description;
        this.details = details;
        this.contextId = contextId;
        this.parentTaskId = parentTaskId;
        this.created = created;
        this.modified = modified;
        this.dueDate = dueDate;
        this.order = order;
        this.complete = complete;
        this.type = type;
    }

    public Task(String description, String details, Integer contextId, Integer parentTaskId, Date created, Date modified,
                    Date startDate, Date dueDate, Integer order, Boolean complete, TaskType type) {
        this(null, description, details, contextId, parentTaskId, created, modified, startDate, dueDate, order, complete, type);
    }

    public Task(Cursor cursor) {
        Projection projection = Task.FULL_PROJECTION;
        this.id = projection.getInteger(cursor, Task.ID);
        this.description = projection.getString(cursor, Task.DESCRIPTION, "");
        this.contextId = projection.getInteger(cursor, Task.CONTEXT_ID);
        this.complete = projection.getBoolean(cursor, Task.COMPLETE);
        this.details = projection.getString(cursor, Task.DETAILS, "");
        this.type = TaskType.getEnum(projection.getInteger(cursor, Task.TYPE));
    }

    /**
     * Copy attributes to values.
     * @param values Values of model attributes.
     */
    public void toValues(ContentValues values) {
        values.put(DESCRIPTION, description);
        values.put(DETAILS, details);
        values.put(CONTEXT_ID, contextId);
        values.put(PARENT_TASK_ID, parentTaskId);
        if (type != null) {
            values.put(TYPE, type.getType());
        }
        if (created != null) {
            values.put(CREATED_DATE, created.getTime());
        }
        if (modified != null) {
            values.put(MODIFIED_DATE, modified.getTime());
        }
        if (startDate != null) {
            values.put(DUE_DATE, dueDate.getTime());
        }
        if (dueDate != null) {
            values.put(DUE_DATE, dueDate.getTime());
        }
        values.put(DISPLAY_ORDER, order);
        if (complete) {
            values.put(COMPLETE, 1);
        } else {
            values.putNull(COMPLETE);
        }
    }

    /**
     * @return The id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id The id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * @return The description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description The description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @return The details
     */
    public String getDetails() {
        return details;
    }

    /**
     * @param details The details to set
     */
    public void setDetails(String details) {
        this.details = details;
    }

    /**
     * @return The contextId
     */
    public Integer getContextId() {
        return contextId;
    }

    /**
     * @param contextId The contextId to set
     */
    public void setContextId(Integer contextId) {
        this.contextId = contextId;
    }

    /**
     * @return The parentTaskId
     */
    public Integer getParentTaskId() {
        return parentTaskId;
    }

    /**
     * @param parentTaskId The parentTaskId to set
     */
    public void setParentTaskId(Integer parentTaskId) {
        this.parentTaskId = parentTaskId;
    }

    /**
     * @return The created
     */
    public Date getCreated() {
        return created;
    }

    /**
     * @param created The created to set
     */
    public void setCreated(Date created) {
        this.created = created;
    }

    /**
     * @return The modified
     */
    public Date getModified() {
        return modified;
    }

    /**
     * @param modified The modified to set
     */
    public void setModified(Date modified) {
        this.modified = modified;
    }

    /**
     * @return The startDate
     */
    public Date getStartDate() {
        return startDate;
    }

    /**
     * @param startDate The startDate to set
     */
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    /**
     * @return The dueDate
     */
    public Date getDueDate() {
        return dueDate;
    }

    /**
     * @param dueDate The dueDate to set
     */
    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }

    /**
     * @return The order
     */
    public Integer getOrder() {
        return order;
    }

    /**
     * @param order The order to set
     */
    public void setOrder(Integer order) {
        this.order = order;
    }

    /**
     * @return The complete
     */
    public Boolean getComplete() {
        return complete;
    }

    /**
     * @param complete The complete to set
     */
    public void setComplete(Boolean complete) {
        this.complete = complete;
    }

    /**
     * @return Type of task.
     */
    public TaskType getType() {
        return type;
    }

    /**
     * @param defaultType Return this type if type == null.
     * @return Type of task.
     */
    public TaskType getType(TaskType defaultType) {
        if (type == null) {
            return defaultType;
        } else {
            return type;
        }
    }

    /**
     * @param type Type of task.
     */
    public void setType(TaskType type) {
        this.type = type;
    }

}
